package net.sf.midollo.servlet;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyHttpServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

  private final String className = this.getClass().getName();
  private String logPath = null;
  private PrintWriter logger = null;

  public void init() throws ServletException {
    openLogFile();
    log("init");
  }

  public void destroy() {
    log("destroy");
    closeLogFile();
  }

  public void log(String s) {
    logToFile(s, null);
  }

  public void log(String s, Throwable throwable) {
    logToFile(s, throwable);
  }

  protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
    try {
      byte[] raw_msg = getFullLogString("doGet\n").getBytes();
      httpServletResponse.setContentType("text/plain");
      httpServletResponse.setContentLength(raw_msg.length);
      OutputStream os = httpServletResponse.getOutputStream();
      os.write(raw_msg);
      os.flush();
    } catch (IOException e) {
      log("doGet", e);
      throw e;
    }
  }

  protected String getLogPath() {
    return this.logPath;
  }

  protected void setLogPath(String logPath) {
    this.logPath = logPath;
  }

  private String getObjectId() {
    int thisId = System.identityHashCode(this);
    return Integer.toHexString(thisId);
  }

  private void openLogFile() {
    if (this.logPath != null) {
      try {
        OutputStream os = new FileOutputStream(this.logPath, true);
        this.logger = new PrintWriter(os, true);
      } catch (FileNotFoundException e) {
      }
    }
  }

  private void closeLogFile() {
    if (this.logger != null) {
      this.logger.close();
      this.logger = null;
    }
  }

  private String getFullLogString(String msg) {
    String strDate = DATE_FORMAT.format(new Date());
    String strOID = getObjectId();
    return strDate + ' ' + this.className + '@' + strOID + ' ' + msg;
  }

  private synchronized void logToFile(String msg, Throwable error) {
    msg = getObjectId() + ' ' + msg;
    if (error != null)
      super.log(msg, error);
    else
      super.log(msg);
    if (this.logger != null) {
      if (error != null) {
        StringWriter sw = new StringWriter();
        error.printStackTrace(new PrintWriter(sw));
        msg += '\n' + sw.toString();
      }
      String header = DATE_FORMAT.format(new Date()) + ' ' + this.className + '@';
      msg = header + msg;
      this.logger.println(msg);
    }
  }
}
